/**
 * @file iter_demo.cpp
 * @author your name (you@domain.com)
 * @brief 模拟实现迭代器
 * @version 0.1
 * @date 2024-03-11
 *
 * @copyright Copyright (c) 2024
 *
 */

/**
 * 写一个单向链表, 模拟迭代器
 */

#include <cstdio>
#include <memory>
#include <utility>

template <typename T>
struct ListNode {
    T val_;
    std::unique_ptr<ListNode> next_;
    ListNode() = default;
    ListNode(T &&val) : val_(std::forward<T>(val)), next_(nullptr) {}
};

template <typename T>
class List {
   public:
    class Iterator {
       public:
        Iterator(ListNode<T> *t) noexcept : t_(t) {}

        T &operator*() { return t_->val_; }

        T *operator->() { return &(t_->val); }

        Iterator &operator++() {
            t_ = t_->next_.get();
            return *this;
        }

        bool operator != (const Iterator &other) noexcept {
            return t_ != other.t_;
        }

       private:
        ListNode<T> *t_;
    };

   public:
    List() = default;
    List(const List &) = delete;
    List &operator=(const List &) = delete;

    void push_front(T &&t) {
        auto node = std::make_unique<ListNode<T>>(std::forward<T>(t));
        node->next_ = std::move(head_);
        head_ = std::move(node);
    }

    bool empty() noexcept { return bool(head_); }

    T &front() noexcept { return head_->val_; }

    Iterator begin() { return Iterator(head_.get()); }

    Iterator end() { return Iterator(nullptr); }

   private:
    std::unique_ptr<ListNode<T>> head_ = nullptr;
};

int main() {
    List<int> l;
    l.push_front(1);
    l.push_front(2);

    auto iter = l.begin();
    for (auto v: l) {
        std::printf("v:%d\n", v);
    }
}
